package com.zs.basic.runoob

/**
 *
 * @description
 * @author madison
 * @date 2021/6/2 22:13
 *
 */
class Runoob {  // 类名为 Runoob
    // 大括号内是类体构成
    var name: String = "zs"
    var url: String = "url"
    var city: String = "shanghai"

    fun foo() {
        print("Foo")
    } // 成员函数
}

class Runoob1 constructor(name: String) {  // 类名为 Runoob
    // 大括号内是类体构成
    var url: String = "http://www.runoob.com"
    var country: String = "CN"
    var siteName = name

    init {
        println("初始化网站名: ${name}")
    }

    // 次构造函数
    constructor (name: String, alexa: Int) : this(name) {
        println("Alexa 排名 $alexa")
    }

    fun printTest() {
        println("我是类的函数")
    }
}

class Empty
class Person {

    var lastName: String = "zhang"
        get() = field.uppercase()   // 将变量赋值后转换为大写
        set

    var no: Int = 100
        get() = field                // 后端变量
        set(value) {
            field = if (value < 10) {       // 如果传入的值小于 10 返回该值
                value
            } else {
                -1         // 如果传入的值大于等于 10 返回 -1
            }
        }

    var heiht: Float = 145.4f
        private set
}

class Person1 constructor(firstName: String) {
    init {
        println("FirstName is $firstName")
    }
}

class Person2(firstName: String) {}

//类也可以有二级构造函数，需要加前缀 constructor:

class Person3 {
    constructor(parent: Person3) {
//        parent.children.add(this)
    }
}

public class MyTest {
    lateinit var subject: TestSubject

    //    @SetUp
    fun setup() {
        subject = TestSubject()
    }

    //    @Test
    fun test() {
        subject.method()  // dereference directly
    }
}

class TestSubject {
    fun method() {
        println("test method")
    }
}

//抽象类
open class Base {
    open fun f() {}
}

abstract class Derived : Base() {
    abstract override fun f()
}

//嵌套类
class Outer {                  // 外部类
    private val bar: Int = 1

    class Nested {             // 嵌套类
        fun foo() = 2
    }
}

//内部类
class Outer1 {
    private val bar: Int = 1
    var v = "成员属性"

    /**嵌套内部类**/
    inner class Inner {
        fun foo() = bar  // 访问外部类成员
        fun innerTest() {
            var o = this@Outer1 //获取外部类的成员变量
            println("内部类可以引用外部类的成员，例如：" + o.v)
        }
    }
}

//匿名内部类
class Test {
    var v = "成员属性"

    fun setInterFace(test: TestInterFace) {
        test.test()
    }
}

/**
 * 定义接口
 */
interface TestInterFace {
    fun test()
}


fun main() {
    val site = Runoob()
    println(site.name)
    println(site.url)

    var person = Person()
    person.lastName = "zhuang"
    println("lastName:${person.lastName}")
    person.no = 9
    println("no:${person.no}")
    person.no = 20
    println("no:${person.no}")
    println(person.heiht)

    val runoob = Runoob1("菜鸟教程", 1000)
    println(runoob.siteName)
    println(runoob.url)
    println(runoob.country)
    runoob.printTest()

    val demo = Outer.Nested().foo()
    println(demo)

    val demo1 = Outer1().Inner().foo()
    println(demo1)
    var demo2 = Outer1().Inner().innerTest()
    println(demo2)

    //匿名内部类
    //采用对象表达式来创建接口对象，即匿名内部类的实例。
    var test = Test()
    test.setInterFace(object : TestInterFace {
        override fun test() {
            println("对象表达式创建匿名内部类的实例")
        }
    })

    /**
     * 类的修饰符
    类的修饰符包括 classModifier 和_accessModifier_:

    classModifier: 类属性修饰符，标示类本身特性。

    abstract    // 抽象类
    final       // 类不可继承，默认属性
    enum        // 枚举类
    open        // 类可继承，类默认是final的
    annotation  // 注解类
    accessModifier: 访问权限修饰符

    private    // 仅在同一个文件中可见
    protected  // 同一个文件中或子类可见
    public     // 所有调用的地方都可见
    internal   // 同一个模块中可见
     */
}

private fun foo1() {} // 在 example.kt 内可见

public var bar: Int = 5 // 该属性随处可见

internal val baz = 6    // 相同模块内可见